/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { formatTime } from '@ohos/hvigor';
import { Component, ComponentPath } from '@ohos/sdkmanager-common';
import fse from 'fs-extra';
import path from 'path';

import { EtsComponentConst, ToolChainsConst } from '../../const/sdk-const.js';
import { ProjectBuildProfile } from '../../options/build/project-build-profile.js';
import { OhosLogger } from '../../utils/log/ohos-logger.js';
import { HmosSdkLoader } from '../hmos-sdk-loader.js';
import { HmsCoreEtsComponent } from '../impl/hms-core-ets-component.js';
import { HmsCoreNativeComponent } from '../impl/hms-core-native-component.js';
import { SdkJavaComponent } from '../impl/sdk-java-component.js';
import { HosSdkToolchainsComponent } from '../impl/sdk-toolchains-component.js';
import { contains } from '../sdk-util.js';

import { CommonSdkInfo } from './common-sdk-info.js';
import ApiMeta = ProjectBuildProfile.ApiMeta;

const _log: OhosLogger = OhosLogger.getLogger('hos-sdk-info');

export class HosSdkInfo extends CommonSdkInfo {
  private ohJavaComponent: SdkJavaComponent | undefined;
  private hosJavaComponent?: SdkJavaComponent;
  private hosToolchainsComponent?: HosSdkToolchainsComponent;
  private hmsCoreNativeComponent?: HmsCoreNativeComponent;
  private hmsCoreEtsComponent?: HmsCoreEtsComponent;
  private readonly hosComponents: string[];
  private readonly hmsCoreComponents: string[];
  protected localHosLibComponents: Map<string, Component> = new Map<string, Component>();
  protected localLibComponents: Map<string, Component> = new Map<string, Component>();
  protected etsV1Path?: string;
  protected etsV2Path?: string;

  constructor(requireComponents: string[], sdkVersion: ApiMeta, sdkDir: string) {
    super(sdkVersion, sdkDir);
    this.sdkDir = sdkDir;
    this.hosComponents = requireComponents;
    this.hmsCoreComponents = [ComponentPath.TOOLCHAINS];
    this.hosComponents.forEach((key) => {
      if (sdkVersion.version > 9 && (key === ComponentPath.ETS || key === ComponentPath.NATIVE)) {
        this.hmsCoreComponents.push(key);
      }
    });
  }

  async setup() {
    const start: [number, number] = process.hrtime();

    // 拿到本地所有现存的组件
    const sdkContainer: HmosSdkLoader = HmosSdkLoader.getInstance();
    this.localLibComponents = await sdkContainer.getHmosSdkComponents(this.sdkVersion, this.hosComponents);
    this.localHosLibComponents = await sdkContainer.getHmsSdkComponents(this.sdkVersion, this.hmsCoreComponents);

    // 初始化ohos、hms组件
    this.hosComponents.forEach((version) => this.initComponent(contains(version, this.localLibComponents)!));
    this.hmsCoreComponents.forEach((version) => this.hmsComponentInit(contains(version, this.localHosLibComponents)!));

    // 用ohos路径下toolchains初始化javaComponent
    this.ohJavaComponent = new SdkJavaComponent(contains(ComponentPath.TOOLCHAINS, this.localLibComponents)!);

    this.hasRollUpPluginInEtsLoader = fse.existsSync(path.resolve(this.getEtsLoader(), ToolChainsConst.ROLL_UP_CONFIG_FILE));
    this.hasRollUpPluginInJsLoader = fse.existsSync(path.resolve(this.getJsLoader(), ToolChainsConst.ROLL_UP_CONFIG_FILE));

    this.etsV1Path = this.getEtsBaseDir();
    this.etsV2Path = path.resolve(this.hmsCoreEtsComponent!.getBaseDir(), EtsComponentConst.ETS1_2);

    const time: [number, number] = process.hrtime(start);
    _log.debug(`Sdk init in ${formatTime(time)}`);
  }

  hmsComponentInit(component: Component) {
    switch (component.getPath()) {
      case ComponentPath.NATIVE:
        this.hmsCoreNativeComponent = new HmsCoreNativeComponent(component);
        break;
      case ComponentPath.ETS:
        this.hmsCoreEtsComponent = new HmsCoreEtsComponent(component);
        break;
      case ComponentPath.TOOLCHAINS:
        this.hosJavaComponent = new SdkJavaComponent(component);
        this.hosToolchainsComponent = new HosSdkToolchainsComponent(component);
        break;
    }
  }

  getEtsBaseDir(): string {
    const etsPath = path.resolve(this.hmsCoreEtsComponent!.getBaseDir(), EtsComponentConst.ETS1_1);
    if (fse.existsSync(etsPath)) {
      return etsPath;
    }

    if (fse.existsSync(this.hmsCoreEtsComponent!.getBaseDir())) {
      return this.hmsCoreEtsComponent!.getBaseDir();
    }

    return etsPath;
  }

  getHmsArkDir() {
    return this.etsV1Path!;
  }

  getHmsNativeDir() {
    return this.hmsCoreNativeComponent!.getBaseDir();
  }

  getHmsToolchainFile() {
    return this.hmsCoreNativeComponent!.getHmsToolchainFile();
  }

  getHmsBiShengToolchainFile() {
    return this.hmsCoreNativeComponent!.getHmsBiShengToolchainFile();
  }

  getRestool(): string {
    return this.toolchainsComponent?.getRestoolPath() ?? '';
  }

  getHosResTool(): string {
    return this.hosJavaComponent!.getRestoolPath();
  }

  // hos
  getModuleSchema(): string {
    return this.hosToolchainsComponent!.getHosModuleSchema();
  }

  getAppSchema(): string {
    return this.hosToolchainsComponent!.getAppSchema();
  }

  getInsightIntentSchema(): string {
    return this.toolchainsComponent!.getInsightIntentSchema();
  }

  getArkDataSchema(): string {
    return this.hosToolchainsComponent!.getArkDataSchema();
  }

  getUtdSchema(): string {
    return this.toolchainsComponent!.getUtdSchema();
  }

  getRichSchema(): string {
    return this.hosToolchainsComponent!.getRichSchema();
  }

  getLiteSchema(): string {
    return this.hosToolchainsComponent!.getLiteSchema();
  }

  getHapSignToolV2(): string {
    return this.hosToolchainsComponent!.getHapSignToolV2();
  }

  getOhosJar(): string {
    return this.hosJavaComponent!.getOhosJarPath();
  }

  getHosModuleSchema(): string {
    return this.hosToolchainsComponent!.getHosModuleSchema();
  }

  getReleaseType(): string {
    return this.hosToolchainsComponent!.getReleaseType();
  }

  getHosToolchainsComponentVersion() {
    return this.hosToolchainsComponent!.getComponentVersion().getVersion();
  }

  getHosToolchainsDir(): string {
    return this.hosToolchainsComponent!.getBaseDir();
  }

  getHosToolchainsLibDir(): string {
    return this.hosToolchainsComponent!.getHosToolchainsLibDir();
  }

  getLibimageTranscoderShared(): string {
    return this.hosToolchainsComponent!.getLibimageTranscoderShared();
  }

  getHosSignTool(): string {
    return this.hosToolchainsComponent!.getHosSignTool();
  }

  getPacSchema(): string {
    return this.hosToolchainsComponent!.getPacSchema();
  }

  getSystemThemeSchema(): string {
    // 闭源sdk需要使用闭源的schema进行校验
    return this.hosToolchainsComponent ? this.hosToolchainsComponent.getSystemThemeSchema() : '';
  }

  getHmsEtsV2ApiPaths(): string[] {
    return [
      path.resolve(this.etsV2Path!, EtsComponentConst.API),
      path.resolve(this.etsV2Path!, EtsComponentConst.KITS),
    ];
  }
}
